#include "bsp_can.h"

void BSP_CAN_Init(void)
{ 
	CAN_Filter_Init();
}

/**
* @brief:      	CAN_Filter_Init
* @param:       hcan: CAN句柄
*               filter_bank: 指定的滤波器组编号
* @retval:     	void
* @details:    	CAN滤波器初始化
**/
void CAN_Filter_Init(void)
{
	CAN_FilterTypeDef can1_filter_st, can2_filter_st; // 使用两个独立的结构体变量
	
	// CAN1 过滤器配置
	can1_filter_st.SlaveStartFilterBank = 14;        // 关键步骤：必须先设置从CAN起始过滤器组[2,6](@ref)
	can1_filter_st.FilterBank = 0;                   // CAN1使用过滤器组0
	can1_filter_st.FilterActivation = ENABLE;
	can1_filter_st.FilterMode = CAN_FILTERMODE_IDMASK;
	can1_filter_st.FilterScale = CAN_FILTERSCALE_32BIT;
	can1_filter_st.FilterIdHigh = 0x0000;
	can1_filter_st.FilterIdLow = 0x0000;
	can1_filter_st.FilterMaskIdHigh = 0x0000;        // 掩码全0，接收所有报文
	can1_filter_st.FilterMaskIdLow = 0x0000;
	can1_filter_st.FilterFIFOAssignment = CAN_RX_FIFO0;
	if (HAL_CAN_ConfigFilter(&hcan1, &can1_filter_st) != HAL_OK) { Error_Handler(); }
	
	// CAN2 过滤器配置
	can2_filter_st.FilterBank = 14;                  // CAN2使用过滤器组14[2,4](@ref)
	can2_filter_st.FilterActivation = ENABLE;
	can2_filter_st.FilterMode = CAN_FILTERMODE_IDMASK;
	can2_filter_st.FilterScale = CAN_FILTERSCALE_32BIT;
	can2_filter_st.FilterIdHigh = 0x0000;
	can2_filter_st.FilterIdLow = 0x0000;
	can2_filter_st.FilterMaskIdHigh = 0x0000;
	can2_filter_st.FilterMaskIdLow = 0x0000;
	can2_filter_st.FilterFIFOAssignment = CAN_RX_FIFO0;
	// 注意：SlaveStartFilterBank只需在配置CAN1时设置一次[2](@ref)
	if (HAL_CAN_ConfigFilter(&hcan2, &can2_filter_st) != HAL_OK) { Error_Handler(); }

	// 启用 CAN1,2
	if (HAL_CAN_Start(&hcan1) != HAL_OK) { Error_Handler(); }
	if (HAL_CAN_Start(&hcan2) != HAL_OK) { Error_Handler();	}
	if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) { Error_Handler(); }
	if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) { Error_Handler(); }
}

/**
* @brief:      	HAL_CAN_RxFifo0MsgPendingCallback
* @param:       hfdcan；FDCAN句柄
* @param:       RxFifo0ITs：中断标志位
* @retval:     	void
* @details:    	HAL库的CAN中断回调函数
**/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	if(hcan == &hcan2) {
		BSP_CAN_RxCallback();
	}
}

/**
* @brief:      	BSP_CAN_SendData
* @param:       hcan:								CAN句柄
* @param:       id: 								CAN设备ID
* @param:       data: 							发送的数据
* @param:       len:  							发送的数据长度
* @retval:     	void
* @details:    	发送数据
**/
uint8_t BSP_CAN_SendData(CAN_HandleTypeDef *hcan, uint16_t id, uint8_t *data, uint32_t len)
{	
	CAN_TxHeaderTypeDef	tx_header;
	
	uint16_t t = 0; //用于计时，放置发送超时

	// 安全断言
	if(len > 8 || data == NULL) return 1;
	
	// 分别处理标准帧和扩展帧
	if(id <= 0x7FF){
		tx_header.StdId = id & 0x7FF;         /* 标准标识符,确保11位ID */
		tx_header.ExtId = 0; 
		tx_header.IDE = CAN_ID_STD;
	}
	else{
		tx_header.ExtId = id & 0x1FFFFFFF;    /* 扩展标识符(29位) */
		tx_header.StdId = 0; 
		tx_header.IDE = CAN_ID_EXT;
	}
	tx_header.RTR = CAN_RTR_DATA; /* 数据帧 */
	tx_header.DLC = len;
	
	// 找到空的发送邮箱，把数据发送出去
	if(HAL_CAN_AddTxMessage(hcan, &tx_header, data, (uint32_t*)CAN_TX_MAILBOX0) != HAL_OK) {
		if(HAL_CAN_AddTxMessage(hcan, &tx_header, data, (uint32_t*)CAN_TX_MAILBOX1) != HAL_OK) {
			if(HAL_CAN_AddTxMessage(hcan, &tx_header, data, (uint32_t*)CAN_TX_MAILBOX2) != HAL_OK){
				return 1;
			}
		}
	}

	//等待发送完成
	while (HAL_CAN_GetTxMailboxesFreeLevel(hcan) != 3)   /* 等待发送完成,所有邮箱为空 */
	{
		t++;
		if (t > 0x100)
		{
			return 1; //发送超时
		}
	}
	return 0;  //发送成功且未超时
}

uint8_t canx_receive(hcan_t *hcan, uint16_t *rec_id, uint8_t *buf)
{	
	CAN_RxHeaderTypeDef rx_header;
  if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, buf) == HAL_OK)
	{
		*rec_id = rx_header.StdId;
		return rx_header.DLC; //接收数据长度
	}
	else
		return 0;
}

uint8_t canx_send_data(CAN_HandleTypeDef *hcan, uint16_t id, uint8_t *data, uint32_t len)
{	
	CAN_TxHeaderTypeDef	tx_header;
	
	tx_header.StdId = id;
	tx_header.ExtId = 0;
	tx_header.IDE   = 0;
	tx_header.RTR   = 0;
	tx_header.DLC   = len;
  /*找到空的发送邮箱，把数据发送出去*/
	if(HAL_CAN_AddTxMessage(hcan, &tx_header, data, (uint32_t*)CAN_TX_MAILBOX0) != HAL_OK) {
		if(HAL_CAN_AddTxMessage(hcan, &tx_header, data, (uint32_t*)CAN_TX_MAILBOX1) != HAL_OK) {
			HAL_CAN_AddTxMessage(hcan, &tx_header, data, (uint32_t*)CAN_TX_MAILBOX2);
    }
  }
  return 0;
}

uint8_t can_rx_data[6][8] = {0};
void BSP_CAN_RxCallback(void)
{
	uint8_t rx_data[8] = {0};
	uint16_t id = 0;
	int index = -1;
	uint8_t len = canx_receive(&hcan2, &id, rx_data);
	len = (len < 8) ? len : 8;
	switch (id)
	{
	case MOTOR_RX_ID_1: {index = 0; break;}
	case MOTOR_RX_ID_2: {index = 1; break;}
	case MOTOR_RX_ID_3: {index = 2; break;}
	case MOTOR_RX_ID_4: {index = 3; break;}
	case MOTOR_RX_ID_5: {index = 4; break;}
	case MOTOR_RX_ID_6: {index = 5; break;}
	}
	if (index < 0 || index > 5) {return;}
	for (uint8_t i = 0; i < len; i++) {
		can_rx_data[index][i] = rx_data[i];
	}
}

// /**
// * @brief:      	can1_rx_callback(void)
// * @param:       void
// * @retval:     	void
// * @details:    	供用户调用的接收弱函数
// **/
// volatile uint8_t can_active_buffer = 0;
// can_buffer_t can_rx_buffers[2] = {0};
// void BSP_CAN2_RX_Callback(CAN_HandleTypeDef *hcan) {
// 	CAN_RxHeaderTypeDef rx_header;
// 	uint8_t rx_data[8] = {0};
// 	static uint8_t buffer_index = 0;
	
// 	if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) {
// 		uint32_t raw_id = (rx_header.IDE == CAN_ID_STD) ? rx_header.StdId : rx_header.ExtId;
		
// 		uint8_t index;
// 		switch(raw_id) {
// 			case MOTOR_RX_ID_1: index = 0; break;
// 			case MOTOR_RX_ID_2: index = 1; break;
// 			case MOTOR_RX_ID_3: index = 2; break;
// 			case MOTOR_RX_ID_4: index = 3; break;
// 			case MOTOR_RX_ID_5: index = 4; break;
// 			case MOTOR_RX_ID_6: index = 5; break;
// 			default: return;
// 		}
		
// 		// 写入非活动缓冲区
// 		uint8_t write_buffer = 1 - can_active_buffer;
// 		for (uint8_t i = 0; i < 8; i++) {
// 			can_rx_buffers[write_buffer].data[index][i] = rx_data[i];
// 		}
		
// 		// 每6个电机数据收齐后切换缓冲区
// 		if (++buffer_index >= 6) {
// 			buffer_index = 0;
// 			can_rx_buffers[write_buffer].ready_flag = 1;
// 			can_active_buffer = write_buffer; // 原子操作切换
// 		}
// 	}
// }
